package com.btm.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

@Component
@ConfigurationProperties(prefix = "system.safe.reject")
public class IpRestrictConfig {
    private List<String> dbIp;

    public List<String> getDbIp() {
        return dbIp;
    }

    public void setDbIp(List<String> dbIp) {
        this.dbIp = dbIp;
    }

    /**
     * 检查指定的数据库IP是否在受限IP列表中
     * 
     * @param dbIp 待检查的数据库IP地址
     * @return 如果IP被限制则返回true，否则返回false
     */
    public boolean isDbIpUnsafe(String dbIp) {
        // 如果配置为空，则默认返回false（表示可用）
        if (this.dbIp == null || this.dbIp.isEmpty()) {
            return false;
        }

        // 如果配置不为空，则进行IP检查
        for (String restrictedIp : this.dbIp) {
            // 跳过空值或空字符串
            if (restrictedIp == null || restrictedIp.trim().isEmpty()) {
                continue;
            }

            if (restrictedIp.contains("/")) {
                // CIDR格式处理
                if (isIpInRange(dbIp, restrictedIp)) {
                    return true;
                }
            } else {
                // 精确IP匹配
                if (restrictedIp.equals(dbIp)) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean isIpInRange(String ip, String cidr) {
        try {
            String[] parts = cidr.split("/");
            String network = parts[0];
            int prefix;
            if (parts.length < 2) {
                prefix = 32;
            } else {
                prefix = Integer.parseInt(parts[1]);
            }

            byte[] networkBytes = ipToBytes(network);
            byte[] ipBytes = ipToBytes(ip);
            
            int networkPrefix = prefix;
            
            // 比较网络前缀部分是否相同
            int numBytes = networkPrefix / 8;
            int numBitsInLastByte = networkPrefix % 8;
            
            for (int i = 0; i < numBytes; i++) {
                if (networkBytes[i] != ipBytes[i]) {
                    return false;
                }
            }
            
            if (numBitsInLastByte > 0) {
                int mask = -1 << (8 - numBitsInLastByte);
                if ((networkBytes[numBytes] & mask) != (ipBytes[numBytes] & mask)) {
                    return false;
                }
            }
            
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    private byte[] ipToBytes(String ip) {
        String[] parts = ip.split(Pattern.quote("."));
        byte[] bytes = new byte[4];
        for (int i = 0; i < 4; i++) {
            bytes[i] = (byte) Integer.parseInt(parts[i]);
        }
        return bytes;
    }
} 